package com.violet.service.manager.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.violet.domain.dto.manager.MCategoryDto;
import com.violet.domain.po.Category;
import com.violet.domain.po.Product;
import com.violet.domain.vo.manager.MCategoryVo;
import com.violet.mapper.CategoryMapper;
import com.violet.service.manager.MCategoryService;
import com.violet.utils.FileUtils;
import com.violet.utils.TransitionUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.List;

@Service
@RequiredArgsConstructor
public class MCategoryServiceImpl extends ServiceImpl<CategoryMapper, Category>
        implements MCategoryService {

    private final TransitionUtils<MCategoryDto, Category, MCategoryVo> transition;
    private final FileUtils fileUtils;

    @Override
    public List<MCategoryVo> getAll() {
        return this.list()
            .stream()
            .map(item -> transition.transition(item, MCategoryVo.class))
            .toList();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MCategoryVo create(MCategoryDto dto) {
        Category category = transition.transition(dto, Category.class);
        try {
            // 保存上传图片
            MultipartFile image = dto.getImage();
            String imageName = fileUtils.uploadImage(image);
            category.setImage(imageName);
            // 存储数据
            baseMapper.insert(category);
        }
        catch (DuplicateKeyException e) { throw new RuntimeException("分类名称重复"); }
        catch (Exception e) { throw new RuntimeException("添加商品分类失败: " + e.getMessage()); }
        finally {
            // 数据未入库，但是图片已保存，删除图片
            if (
                category.getImage() != null &&
                !category.getImage().isEmpty() &&
                !baseMapper.exists(new LambdaQueryWrapper<Category>().eq(Category::getId, category.getId()))
            ) {
                fileUtils.deleteImage(category.getImage());
            }
        }

        return transition.transition(category, MCategoryVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE)
    public Boolean deleteById(String id) {
        Category category = baseMapper.getByIdAndProductCountIsZeroWithPessimisticLock(id);
        if (category == null) throw new RuntimeException("商品分类不存在 或者 商品分类下有商品，无法删除");
        int i = baseMapper.deleteById(category);
        if (i == 1) {
            // 删除图片
            fileUtils.deleteImage(category.getImage());
            // 返回
            return true;
        }
        else throw new RuntimeException("删除商品失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ)
    public MCategoryVo updateById(String id, MCategoryDto dto) {
        // 获取商品 (悲观锁)
        Category category = baseMapper.getByIdWithPessimisticLock(id);
        if (category == null) throw new RuntimeException("商品分类不存在");
        // 拷贝数据
        transition.copy(dto, category);
        try {
            // 图片不为空，则更新图片
            if (dto.getImage() != null) {
                fileUtils.deleteImage(category.getImage());
                String fileName = fileUtils.uploadImage(dto.getImage());
                category.setImage(fileName);
            }
            // 入库
            baseMapper.updateById(category);
        }
        catch (DuplicateKeyException e) { throw new RuntimeException("分类名称重复"); }
        catch (Exception e) { throw new RuntimeException("添加商品失败: " + e.getMessage()); }
        // 返回
        return transition.transition(category, MCategoryVo.class);
    }

}
